package net.falcon;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.falcon.data.Arena;
import net.falcon.data.Arena.GameState;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;

public class FalconArena extends JavaPlugin implements Listener {
	
	public static final PlayerEventListener playerListener = new PlayerEventListener();
	public static FalconArena instance;
	public ArrayList<Arena> arenas = new ArrayList<Arena>();
	
	public FalconArena() {
		instance = this;
	}
	
	@Override
	public void onEnable() {
		Bukkit.getLogger().info("PluginTemplate loaded!");
		Bukkit.getPluginManager().registerEvents(this, this);
		Bukkit.getPluginManager().registerEvents(playerListener, this);
		Util.loadFromConfig();
	}

	@Override
	public void onDisable() {
		Util.saveMaps();
	}
	
	//remember to register any new commands in the plugin.yml!
	
	//metadata
	//fa.map: joined map
	//fa.lives: lives
	//fa.wall.ew
	//fa.wall.ns
	
	//fa list
	//fa join
	//fa start (force starting a game)
	//fa arena (name)(pt1)(pt2)(save)
	@Override
	public boolean onCommand(CommandSender sender, Command command, String label, String[] args ) {
		if(!(sender instanceof Player)) { //sent from console
			return true;
		}
		Player origin = (Player)sender;
		if(!command.getName().equals("fa")) {
			return false;
		}
		
		if(args.length == 0) { //no additional arguments, just "/fa"
			Util.sendMessage(origin,ChatColor.AQUA + "FalconArena Alpha (0.0.1)");
			Util.sendMessage(origin,ChatColor.AQUA + "By Sparrow, Atomic, Veggie");
			return true;
		}
		
		if(args.length > 1) {
			if(args[0].equals("arena")) {
				//handle arenas
				if(args[1].equals("name")) {//TODO what if the command is just "/fa arena name"
					Util.sendMessage(origin,"Set Arena Name to '" + args[2]);
					Util.setMetadata(origin, "tempArena.name", args[2]);
				}
				if(args[1].equals("pt1")) {
					Util.sendMessage(origin,"Set Pt1.");
					Util.setMetadata(origin, "tempArena.pt1", origin.getLocation().toVector());
				}
				if(args[1].equals("pt2")) {
					Util.sendMessage(origin,"Set Pt2.");
					Util.setMetadata(origin, "tempArena.pt2", origin.getLocation().toVector());
				}
				if(args[1].equals("inv")) {
					Util.sendMessage(origin,"Set Default Inventory.");
					Util.setMetadata(origin, "tempArena.inventory", Arrays.asList(origin.getInventory().getContents()));
				}
				
				if(args[1].equals("lives")) {
					Util.sendMessage(origin,"Set Life Count.");
					Util.setMetadata(origin, "tempArena.lives", Integer.parseInt(args[2]));
				}
				
				if(args[1].equals("spawn")) {
					Util.sendMessage(origin,"Set Another Spawn.");
					if(Util.getMetadata(origin, "tempArena.spawns") == null) {
						Util.setMetadata(origin, "tempArena.spawns", new ArrayList<Vector>());
					}
					Util.getTempSpawns(origin).add(origin.getLocation().toVector());
					Location l = origin.getLocation();
					origin.getWorld().getBlockAt(l.getBlockX(), l.getBlockY() - 1, l.getBlockZ()).setType(Material.LAPIS_BLOCK);
				}
				if(args[1].equals("save")) {
					//make sure everything is set
					if(Util.getMetadata(origin, "tempArena.name") == null) {
						Util.sendMessage(origin,"Please set a name for this arena before saving it.");
						return true;
					}
					if(Util.getMetadata(origin, "tempArena.pt1") == null) {
						Util.sendMessage(origin,"Please set points for this arena before saving it.");
						return true;
					}
					if(Util.getMetadata(origin, "tempArena.pt2") == null) {
						Util.sendMessage(origin,"Please set another point for this arena before saving it.");
						return true;
					}
					
					if(Util.getMetadata(origin, "tempArena.inventory") == null) {
						Util.sendMessage(origin,"Please set a default inventory for this arena before saving it.");
						return true;
					}
					if(Util.getTempSpawns(origin) == null || Util.getTempSpawns(origin).size() <= 0) {
						Util.sendMessage(origin,"Please add at least 1 spawn point.");
						return true;
					}
					
					
					//actually create + add the arena
					Arena a = new Arena();
					a.setName((String)Util.getMetadata(origin, "tempArena.name"));
					a.setPt1((Vector)Util.getMetadata(origin, "tempArena.pt1"));
					a.setPt2((Vector)Util.getMetadata(origin, "tempArena.pt2"));
					a.setSpawnInv((List<ItemStack>)Util.getMetadata(origin, "tempArena.inventory"));
					a.setSpawns(Util.getTempSpawns(origin));
					Integer lives = (Integer) Util.getMetadata(origin, "tempArena.lives");
					a.setLives((lives==null)?1:lives);
					addArena(a);
					Util.sendMessage(origin,"Arena Added!");
					
					//reset the temp-arena data
					Util.setMetadata(origin, "tempArena.name", null);
					Util.setMetadata(origin, "tempArena.pt1", null);
					Util.setMetadata(origin, "tempArena.pt2", null);
					Util.setMetadata(origin, "tempArena.inventory", null);
					Util.setMetadata(origin, "tempArena.lives", null);
				}
				
				return true;
			}
		}
		
		if(args[0].equals("list")) {
			//list ongoing/joinable games
			Util.sendMessage(origin,ChatColor.AQUA + "Arenas:");
			for(Arena a : arenas) {
				Util.sendMessage(origin,ChatColor.AQUA + a.getName() + ": " + a.getPlayerCount() + " / " + a.getMaxPlayers()); //change sort/color if joinable
			}
		}
		
		if(args[0].equals("spawn")) {
			origin.teleport(origin.getWorld().getSpawnLocation());
		}
		
		if(args[0].equals("leave")) {
			Arena a = (Arena) Util.getArena(origin);
			if (Util.isInGame(origin)) {
				a.eliminatePlayer(origin);
				origin.damage(999999);
			} else {
				Util.sendMessage(origin, "You are not in a game.");
			}
		}
		
		if(args[0].equals("join")) {
			if(args.length == 1 ) {
				Util.sendMessage(origin,"/fa join (mapname)");
				return true;
			}
			Arena ar = Util.lookupArena(args[1]);
			if(ar == null) {
				Util.sendMessage(origin,"That map doesn't exist.");
				return true;
			}
			if(ar.isFull()) {
				Util.sendMessage(origin,"That map is full.");
				return true;
			}
			if(ar.getGameState() != GameState.STARTING) {
				Util.sendMessage(origin,"This game has already started.");
				return true;
			}
			
			ar.addPlayer(origin);
			//join a specific game
			if(!Util.isInGame(origin)) {
				Util.setMetadata(origin, "fa.map", ar);
			} else {
				Util.sendMessage(origin,"You are already in a game.");
				return true;
			}
			
			Util.sendMessage(origin,"Joined map.");
			return true;
		}
		
		if(args[0].equals("start")) {
			//admin forces a start of his own game
			//TODO what if not in game?
			Util.getArena(origin).startGame();
		}
		
		return true;
	}
	
	public void addArena(Arena a) {
		arenas.add(a);
	}
	
	
	
	
	
	

}
